package core;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.Image;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.BarcodeEAN;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;

/**
 * This class is intended to be used by ItemFacade (and, by extension, the Controller classes
 * in our MVC model) to print a list of barcodes for each new Item added in the Batch Add
 * Items View.  This class is an implementation of IBarcodePrinter that uses the iTextPDF
 * library to print barcode reports, and hence expects a file name as its location parameter.
 * @author Royce
 *
 */
public class ITextPDFBarcodePrinter implements IBarcodePrinter {
	private final int NUM_COLS = 6;
	
	
	/**
	 * Default no-arg constructor
	 */
	protected ITextPDFBarcodePrinter() {
		
	}
	
	@Override
	/**
	 * @inheritDoc
	 */ 
	public void printBarcodes(List<Item> items) throws IOException {
		assert(items != null);
		if (items.isEmpty()) {
			//don't bother
			return;
		}
		
		//generate the filename
		String _fileName;
		StringBuilder dateBuilder = new StringBuilder();
		dateBuilder.append("report");
		dateBuilder.append(Calendar.getInstance().get(GregorianCalendar.MONTH));
		dateBuilder.append(Calendar.getInstance().get(GregorianCalendar.DAY_OF_MONTH));
		dateBuilder.append(Calendar.getInstance().get(GregorianCalendar.YEAR));
		dateBuilder.append(Calendar.getInstance().get(GregorianCalendar.HOUR));
		dateBuilder.append(Calendar.getInstance().get(GregorianCalendar.MINUTE));
		dateBuilder.append(Calendar.getInstance().get(GregorianCalendar.SECOND));
		dateBuilder.append(".pdf");
		_fileName = dateBuilder.toString();
		//System.err.println(_fileName);
		
		try {
			//prep the writer
			Document document = new Document();
			Font font = FontFactory.getFont(FontFactory.HELVETICA);
			font.setSize(6);
			PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(_fileName));
			document.setMargins(20F, 20F, 30F, 30F);
			document.open();
		
			
			
			//add barcodes to a table
			PdfPTable table = new PdfPTable(NUM_COLS);
			table.setWidthPercentage(100);
			table.getDefaultCell().setBorder(PdfPCell.NO_BORDER);
			
			for (int i = 0; i < items.size(); i++) {
				Item item = items.get(i);
				PdfPTable innerTable = new PdfPTable(1);
				innerTable.setWidthPercentage(100);
				innerTable.getDefaultCell().setBorder(PdfPCell.NO_BORDER);
				
				//description
				PdfPCell description = new PdfPCell(new Phrase(item.getDescription(), font));
				description.setBorder(PdfPCell.NO_BORDER);
				
				//current date + expiration date
				StringBuilder sb = new StringBuilder();
				Calendar entryDate = item.getEntryDate();
				Calendar expDate = item.getExpirationDate();
				
				sb.append(entryDate.get(GregorianCalendar.MONTH) + 1).append("\\");
				sb.append(entryDate.get(GregorianCalendar.DAY_OF_MONTH)).append("\\");
				sb.append(entryDate.get(GregorianCalendar.YEAR));
				
				if (!expDate.equals(entryDate)) {
					sb.append(" exp ");
					sb.append(expDate.get(GregorianCalendar.MONTH) + 1).append("\\");
					sb.append(expDate.get(GregorianCalendar.DAY_OF_MONTH)).append("\\");
					sb.append(expDate.get(GregorianCalendar.YEAR));
				}
				
				PdfPCell date = new PdfPCell(new Phrase(sb.toString(), font));
				date.setBorder(PdfPCell.NO_BORDER);
				
				//barcode image
				BarcodeEAN barcode = new BarcodeEAN();
				barcode.setCode(item.getBarcodeString());
				barcode.setCodeType(com.itextpdf.text.pdf.Barcode.UPCA);
				Image barcodeImage = barcode.createImageWithBarcode(writer.getDirectContent(), 
						                                            null, null);
				barcodeImage.setAlignment(Element.ALIGN_CENTER);
				
				PdfPCell barcodeCell = new PdfPCell(barcodeImage);
				barcodeCell.setBorder(PdfPCell.NO_BORDER);
				
				//add everything
				innerTable.addCell(description);
				innerTable.addCell(date);
				innerTable.addCell(barcodeCell);
				table.addCell(innerTable);
			}
		
			//complete any empty rows
			table.completeRow();		
			
			//print the table
			document.add(table);
			
			//close the writer, open the pdf file
			document.close();
			java.awt.Desktop.getDesktop().open(new File(_fileName));
		}
		catch (DocumentException e) {
			throw new IOException("DocumentException");
		}
		
	}
}
